home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / tcp_vmsl.c < prev    next >
C/C++ Source or Header  |  1995-09-09  |  9KB  |  335 lines

  1. /*
  2.  * Program:    VMS TCP/IP routines for Netlib.
  3.  *
  4.  * Author:    Yehavi Bourvine, The Hebrew University of Jerusalem
  5.  *        Internet: Yehavi@VMS.huji.ac.il
  6.  *
  7.  * Date:    2 August 1994
  8.  * Last Edited:    8 September 1995
  9.  *
  10.  * Copyright 1995 by the University of Washington
  11.  *
  12.  *  Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose and without fee is hereby granted, provided
  14.  * that the above copyright notice appears in all copies and that both the
  15.  * above copyright notice and this permission notice appear in supporting
  16.  * documentation, and that the name of the University of Washington not be
  17.  * used in advertising or publicity pertaining to distribution of the software
  18.  * without specific, written prior permission.    This software is made available
  19.  * "as is", and
  20.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  21.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  22.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  23.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  24.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  25.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  26.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  27.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  28.  *
  29.  */
  30.  
  31.  
  32. #include <descrip.h>
  33.  
  34. /* TCP/IP manipulate parameters
  35.  * Accepts: function code
  36.  *        function-dependent value
  37.  * Returns: function-dependent return value
  38.  */
  39.  
  40. void *tcp_parameters (long function,void *value)
  41. {
  42.   return NIL;
  43. }
  44.  
  45.  
  46. /* TCP/IP open
  47.  * Accepts: host name
  48.  *        contact service name
  49.  *        contact port number
  50.  * Returns: TCP/IP stream if success else NIL
  51.  */
  52.  
  53. TCPSTREAM *tcp_open (char *host,char *service,long port)
  54. {
  55.   TCPSTREAM *stream = NIL;
  56.   unsigned long sock;
  57.   int status;
  58.   char *s;
  59.   char hostname[MAILTMPLEN];
  60.   char tmp[MAILTMPLEN];
  61.                 /* hostname to connect to */
  62.   struct dsc$descriptor HostDesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
  63.                 /* assign a local socket */
  64.   if (!((status = net_assign (&sock)) & 0x1)) {
  65.     sprintf (tmp,"Unable to assign to net, status=%d",status);
  66.     mm_log (tmp,ERROR);
  67.     return NIL;
  68.   }
  69.   if (!((status = net_bind (&sock,1)) & 0x1)) {
  70.     sprintf (tmp,"Unable to create local socket, status=%d",status);
  71.     mm_log (tmp,ERROR);
  72.     return NIL;
  73.   }
  74.                 /* open connection */
  75.   HostDesc.dsc$w_length = strlen (host);
  76.   HostDesc.dsc$a_pointer = host;
  77.   if (!((status = tcp_connect (&sock,&HostDesc,port)) & 0x1)) {
  78.     sprintf (tmp,"Can't connect to %.80s,%lu: %s",host,port,strerror (errno));
  79.     mm_log (tmp,ERROR);
  80.     return NIL;
  81.   }
  82.                 /* create TCP/IP stream */
  83.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  84.                 /* copy official host name */
  85.   stream->host = cpystr (hostname);
  86.                 /* copy local host name */
  87.   stream->localhost = cpystr (mylocalhost ());
  88.   stream->port = port;        /* copy port number */
  89.                 /* init sockets */
  90.   stream->tcpsi = stream->tcpso = sock;
  91.   stream->ictr = 0;        /* init input counter */
  92.   return stream;        /* return success */
  93. }
  94.  
  95. /* TCP/IP authenticated open
  96.  * Accepts: host name
  97.  *        service name
  98.  *        returned user name
  99.  * Returns: TCP/IP stream if success else NIL
  100.  */
  101.  
  102. TCPSTREAM *tcp_aopen (char *host,char *service,char *usrnam)
  103. {
  104.   return NIL;
  105. }
  106.  
  107. /* TCP/IP receive line
  108.  * Accepts: TCP/IP stream
  109.  * Returns: text line string or NIL if failure
  110.  */
  111.  
  112. char *tcp_getline (TCPSTREAM *stream)
  113. {
  114.   int n,m;
  115.   char *st,*ret,*stp;
  116.   char c = '\0';
  117.   char d;
  118.                 /* make sure have data */
  119.   if (!tcp_getdata (stream)) return NIL;
  120.   st = stream->iptr;        /* save start of string */
  121.   n = 0;            /* init string count */
  122.   while (stream->ictr--) {    /* look for end of line */
  123.     d = *stream->iptr++;    /* slurp another character */
  124.     if ((c == '\015') && (d == '\012')) {
  125.       ret = (char *) fs_get (n--);
  126.       memcpy (ret,st,n);    /* copy into a free storage string */
  127.       ret[n] = '\0';        /* tie off string with null */
  128.       return ret;
  129.     }
  130.     n++;            /* count another character searched */
  131.     c = d;            /* remember previous character */
  132.   }
  133.                 /* copy partial string from buffer */
  134.   memcpy ((ret = stp = (char *) fs_get (n)),st,n);
  135.                 /* get more data from the net */
  136.   if (!tcp_getdata (stream)) return NIL;
  137.                 /* special case of newline broken by buffer */
  138.   if ((c == '\015') && (*stream->iptr == '\012')) {
  139.     stream->iptr++;        /* eat the line feed */
  140.     stream->ictr--;
  141.     ret[n - 1] = '\0';        /* tie off string with null */
  142.   }
  143.                 /* else recurse to get remainder */
  144.   else if (st = tcp_getline (stream)) {
  145.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  146.     memcpy (ret,stp,n);        /* copy first part */
  147.     memcpy (ret + n,st,m);    /* and second part */
  148.     fs_give ((void **) &stp);    /* flush first part */
  149.     fs_give ((void **) &st);    /* flush second part */
  150.     ret[n + m] = '\0';        /* tie off string with null */
  151.   }
  152.   return ret;
  153. }
  154.  
  155. /* TCP/IP receive buffer
  156.  * Accepts: TCP/IP stream
  157.  *        size in bytes
  158.  *        buffer to read into
  159.  * Returns: T if success, NIL otherwise
  160.  */
  161.  
  162. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  163. {
  164.   unsigned long n;
  165.   char *bufptr = buffer;
  166.   while (size > 0) {        /* until request satisfied */
  167.     if (!tcp_getdata (stream)) return NIL;
  168.     n = min (size,stream->ictr);/* number of bytes to transfer */
  169.                 /* do the copy */
  170.     memcpy (bufptr,stream->iptr,n);
  171.     bufptr += n;        /* update pointer */
  172.     stream->iptr +=n;
  173.     size -= n;            /* update # of bytes to do */
  174.     stream->ictr -=n;
  175.   }
  176.   bufptr[0] = '\0';        /* tie off string */
  177.   return T;
  178. }
  179.  
  180.  
  181. /* TCP/IP receive data
  182.  * Accepts: TCP/IP stream
  183.  * Returns: T if success, NIL otherwise
  184.  */
  185.  
  186. long tcp_getdata (TCPSTREAM *stream)
  187. {
  188.   char tmp[MAILTMPLEN];
  189.   int i,status;
  190.   /* Note: the doc says we need here dynamic descriptor, but we need static
  191.    * one... */
  192.   struct dsc$descriptor BufDesc = {BUFLEN,DSC$K_DTYPE_T,DSC$K_CLASS_S,
  193.                      stream->ibuf};
  194.   static short iosb[4];
  195.   if (stream->tcpsi < 0) return NIL;
  196.   while (stream->ictr < 1) {    /* if nothing in the buffer */
  197.     if (!((status = tcp_receive(&(stream->tcpsi), &BufDesc, iosb)) & 0x1)) {
  198.       sprintf (tmp,"Error reading from TcpIp/NETLIB, status=%d",status);
  199.       mm_log (tmp,ERROR);
  200.       return tcp_abort (stream);
  201.     }
  202.     if (iosb[1] > BUFLEN) i = BUFLEN;
  203.     else i = iosb[1];
  204.     if (i < 1) return tcp_abort (stream);
  205.     stream->ictr = i;        /* set new byte count */
  206.     stream->iptr = stream->ibuf;/* point at TCP buffer */
  207.   }
  208.   return T;
  209. }
  210.  
  211. /* TCP/IP send string as record
  212.  * Accepts: TCP/IP stream
  213.  *        string pointer
  214.  * Returns: T if success else NIL
  215.  */
  216.  
  217. long tcp_soutr (TCPSTREAM *stream,char *string)
  218. {
  219.   return tcp_sout (stream,string,(unsigned long) strlen (string));
  220. }
  221.  
  222.  
  223. /* TCP/IP send string
  224.  * Accepts: TCP/IP stream
  225.  *        string pointer
  226.  *        byte count
  227.  * Returns: T if success else NIL
  228.  */
  229.  
  230. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  231. {
  232.   int status;
  233.   struct dsc$descriptor_s BufDesc = {strlen(string),DSC$K_DTYPE_T,
  234.                        DSC$K_CLASS_S,string };
  235.                 /* 2 = Do not add \r\n */
  236.   return ((status = tcp_send (&(stream->tcpso),&BufDesc,2)) & 0x1) ? T :
  237.     tcp_abort (stream);
  238. }
  239.  
  240. /* TCP/IP close
  241.  * Accepts: TCP/IP stream
  242.  */
  243.  
  244. void tcp_close (TCPSTREAM *stream)
  245. {
  246.   tcp_abort (stream);        /* nuke the stream */
  247.                 /* flush host names */
  248.   fs_give ((void **) &stream->host);
  249.   fs_give ((void **) &stream->localhost);
  250.   fs_give ((void **) &stream);    /* flush the stream */
  251. }
  252.  
  253.  
  254. /* TCP/IP abort stream
  255.  * Accepts: TCP/IP stream
  256.  * Returns: NIL always
  257.  */
  258.  
  259. long tcp_abort (TCPSTREAM *stream)
  260. {
  261.   if (stream->tcpsi >= 0) {    /* no-op if no socket */
  262.                 /* nuke the socket */
  263.     tcp_disconnect (&(stream->tcpsi));
  264.     stream->tcpsi = stream->tcpso = -1;
  265.   }
  266.   return NIL;
  267. }
  268.  
  269. /* TCP/IP get host name
  270.  * Accepts: TCP/IP stream
  271.  * Returns: host name for this stream
  272.  */
  273.  
  274. char *tcp_host (TCPSTREAM *stream)
  275. {
  276.   return stream->host;        /* return host name */
  277. }
  278.  
  279.  
  280. /* TCP/IP return port for this stream
  281.  * Accepts: TCP/IP stream
  282.  * Returns: port number for this stream
  283.  */
  284.  
  285. long tcp_port (TCPSTREAM *stream)
  286. {
  287.   return stream->port;        /* return port number */
  288. }
  289.  
  290.  
  291. /* TCP/IP get local host name
  292.  * Accepts: TCP/IP stream
  293.  * Returns: local host name
  294.  */
  295.  
  296. char *tcp_localhost (TCPSTREAM *stream)
  297. {
  298.   return stream->localhost;    /* return local host name */
  299. }
  300.  
  301. /* TCP/IP get server host name
  302.  * Accepts: pointer to destination
  303.  * Returns: string pointer if got results, else NIL
  304.  */
  305.  
  306. char *tcp_clienthost (char *dst)
  307. {
  308.   return "UNKNOWN";        /* needs to be written */
  309. }
  310.  
  311.  
  312. /* Return my local host name
  313.  * Returns: my local host name
  314.  */
  315.  
  316. char *mylocalhost ()
  317. {
  318.   int status;
  319.   char tmp[MAILTMPLEN];
  320.   if (!myLocalHost) {        /* have local host yet? */
  321.                 /* receives local host name */
  322.     struct dsc$descriptor LocalhostDesc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL};
  323.     if (!((status = net_get_hostname (&LocalhostDesc)) & 0x1)) {
  324.       sprintf (tmp,"Can't get local hostname, status=%d",status);
  325.       mm_log (tmp,ERROR);
  326.       return "UNKNOWN";
  327.     }
  328.     strncpy (tmp,LocalhostDesc.dsc$a_pointer,LocalhostDesc.dsc$w_length);
  329.     tmp[LocalhostDesc.dsc$w_length] = '\0';
  330.     str$free1_dx (&LocalhostDesc);
  331.     myLocalHost = cpystr (tmp);
  332.   }
  333.   return myLocalHost;
  334. }
  335.